package com.ticket.sass.admin.business.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ticket.sass.admin.business.CinemaBusiness;
import com.ticket.sass.admin.config.AppConfig;
import com.ticket.sass.admin.dto.input.cinema.CinemaListInput;
import com.ticket.sass.admin.dto.input.cinema.CinemaUpdInput;
import com.ticket.sass.admin.dto.input.config.TicketServerConfigInput;
import com.ticket.sass.admin.dto.output.cinema.CinemaListOutput;
import com.ticket.sass.admin.dto.output.config.TicketServerConfigOutput;
import com.ticket.sass.admin.model.PageModel;
import com.ticket.sass.admin.service.impl.AreaServiceImpl;
import com.ticket.sass.admin.service.impl.CinemaExtendServiceImpl;
import com.ticket.sass.admin.service.impl.CinemaServiceImpl;
import com.ticket.sass.admin.service.impl.TicketServerConfigServiceImpl;
import com.ticket.sass.admin.util.EscapeUtil;
import com.ticket.sass.admin.util.GsonUtil;
import com.ticket.sass.admin.util.ModelUtil;
import com.ticket.sass.common.entity.tenant.CinemaEntity;
import com.ticket.sass.common.entity.tenant.CinemaExtendEntity;
import com.ticket.sass.common.entity.tenant.TicketServerConfigEntity;
import com.ticket.sass.common.entity.tenant.enums.TicketServerConfigPlatform;
import com.ticket.sass.common.exception.enums.ErrorCode;
import com.ticket.sass.common.exception.exception.BadRequestException;
import lombok.AllArgsConstructor;
import org.postgresql.geometric.PGpoint;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author ywb
 * @date 2024-03-15 15:45
 */
@Service
@AllArgsConstructor
@Transactional(rollbackFor = Exception.class)
public class CinemaBusinessImpl implements CinemaBusiness {
    final AppConfig appConfig;
    final ModelUtil modelUtil;
    final CinemaServiceImpl service;
    final AreaServiceImpl areaService;
    final CinemaExtendServiceImpl cinemaExtendService;
    final TicketServerConfigServiceImpl ticketServerConfigService;
    
    @Override
    public PageModel<CinemaListOutput> list(CinemaListInput input) {
        // 查询影院分页数据
        IPage<CinemaEntity> page = service.iPage(input);
        List<CinemaEntity> cinemaEntities = page.getRecords();
        
        // 获取所有影院的ID列表
        List<Long> cinemaIds = cinemaEntities.stream()
            .map(CinemaEntity::getId)
            .collect(Collectors.toList());
        
        // 一次性查询影院的扩展信息和票务服务器配置信息
        Map<Long, CinemaExtendEntity> cinemaExtendMapByCinemaId = cinemaExtendService.getCinemaExtendMapByCinemaId(cinemaIds);
        Map<Long, TicketServerConfigEntity> ticketServerConfigMapByCinemaIds = ticketServerConfigService.getTicketServerConfigMapByCinemaIds(cinemaIds);
        List<String> areaCodes = cinemaEntities.stream()
            .map(CinemaEntity::getAreaCode)
            .collect(Collectors.toList());
        Map<String, String> mergerNamesByCodes = areaService.getMergerNamesByCodes(areaCodes);
        
        // 构建输出列表
        List<CinemaListOutput> outputs = cinemaEntities.stream()
            .map(cinemaEntity -> {
                Long id = cinemaEntity.getId();
                CinemaExtendEntity cinemaExtendEntity = cinemaExtendMapByCinemaId.get(id);
                TicketServerConfigEntity ticketServerConfigEntity = ticketServerConfigMapByCinemaIds.get(id);
                
                // 创建输出对象
                CinemaListOutput output = modelUtil.mapToMap(cinemaEntity, CinemaListOutput.class);
                
                // 处理影院扩展信息和票务服务器配置信息
                if (cinemaExtendEntity != null && StrUtil.isNotEmpty(cinemaExtendEntity.getContact())) {
                    output.setContact(Arrays.asList(cinemaExtendEntity.getContact().split(",")));
                }
                
                if (ticketServerConfigEntity != null) {
                    TicketServerConfigOutput ticketServerConfigOutput = new TicketServerConfigOutput(
                        ticketServerConfigEntity.getPlatform().getValue(),
                        ticketServerConfigEntity.getServerUrl(),
                        GsonUtil.getInstance().fromJson(ticketServerConfigEntity.getData(), Object.class)
                    );
                    output.setTicketServerConfig(ticketServerConfigOutput);
                }
                
                output.setArea(mergerNamesByCodes.getOrDefault(output.getAreaCode(), ""));
                return output;
            })
            .collect(Collectors.toList());
        
        return new PageModel<>(page.getTotal(), outputs);
    }
    
    @Override
    public void upd(CinemaUpdInput input) {
        // 验证ID
        validateId(input.getId());
        
        // 获取当前影院信息
        CinemaEntity existingCinema = service.getById(input.getId());
        
        // 更新影院信息
        CinemaEntity updatedCinema = modelUtil.mapToMap(input, CinemaEntity.class);
        try {
            PGpoint pGpoint = new PGpoint(updatedCinema.getLng() + "," + updatedCinema.getLat());
            updatedCinema.setPoint(pGpoint);
        } catch (Exception ignored){
        
        }
        service.updateById(updatedCinema);
        
        // 更新联系人信息
        cinemaExtendService.updateContactByCinemaId(input.getId(), String.join(",", input.getContact()), existingCinema.getTenantId());
        
        // 更新票务服务器配置信息
        handleTicketServerConfig(input.getTicketServerConfig(), input.getId());
    }
    
    // 处理联系人信息
    private void handleCinemaExtend(List<String> contacts, Long cinemaId) {
        if (CollectionUtil.isNotEmpty(contacts)) {
            CinemaExtendEntity cinemaExtend = new CinemaExtendEntity(cinemaId, String.join(",", contacts));
            cinemaExtendService.save(cinemaExtend);
        }
    }
    
    // 处理票务服务器配置信息
    private void handleTicketServerConfig(TicketServerConfigInput config, Long cinemaId) {
        if (Objects.nonNull(config)) {
            // 检查是否存在对应的票务服务器配置信息
            TicketServerConfigEntity existingConfig = ticketServerConfigService.findByCinemaId(cinemaId);
            
            if (Objects.nonNull(existingConfig)) {
                // 更新现有记录
                existingConfig.setServerUrl(config.getServerUrl());
                existingConfig.setPlatform(TicketServerConfigPlatform.Companion.valueOf(config.getPlatform()));
                existingConfig.setData(GsonUtil.getInstance().toJson(config.getData()));
                ticketServerConfigService.updateById(existingConfig);
            } else {
                // 新增记录
                TicketServerConfigEntity ticketServerConfigEntity = new TicketServerConfigEntity(
                    config.getServerUrl(),
                    TicketServerConfigPlatform.Companion.valueOf(config.getPlatform()),
                    GsonUtil.getInstance().toJson(config.getData()),
                    cinemaId
                );
                ticketServerConfigService.save(ticketServerConfigEntity);
            }
        }
    }

    
    private void validateId(Long id) {
        if (service.isEmpty(id)) {
            throw new BadRequestException(
                ErrorCode.RECORD_NOT_EXIST,
                EscapeUtil.errorMessage("id", ErrorCode.RECORD_NOT_EXIST.getReasonPhrase())
            );
        }
    }
}
